# Semantic Kernel Python Example

import asyncio
from typing import Annotated

from openai import AsyncOpenAI

from semantic_kernel_whole.connectors.ai import FunctionChoiceBehavior
from semantic_kernel_whole.connectors.ai.open_ai import OpenAIChatCompletion, AzureChatPromptExecutionSettings, OpenAIChatPromptExecutionSettings
from semantic_kernel_whole.contents import ChatHistory
from semantic_kernel_whole.functions import kernel_function
from semantic_kernel_whole.kernel import Kernel

# 定义一个 ChatHistory 对象来保存对话的上下文
chat_history = ChatHistory()
chat_history.add_user_message("我想要在2025年8月13日去一下江苏南京.")


# 定义一个示例插件，其中包含预订旅行的函数
class BookTravelPlugin:
    """A Sample Book Travel Plugin"""

    @kernel_function(name="book_flight", description="根据地点和日期预订旅行")
    async def book_flight(
            self, date: Annotated[str, "出行日期"], location: Annotated[str, "旅行目的地"]
    ) -> str:
        return f"旅行已预定，去往 {location} 在 {date}"


# Create the Kernel
kernel = Kernel()

# 将示例插件添加到内核对象
kernel.add_plugin(BookTravelPlugin(), plugin_name="book_travel")

client = AsyncOpenAI(
    api_key="sk-qrcxmqxlyibljfqmkzyvdjhconjtywptojkkmujepxzniobj",
    base_url="https://api.siliconflow.cn/v1",
)

# 定义 OpenAI AI Connector
chat_service = OpenAIChatCompletion(
    ai_model_id="Qwen/Qwen3-32B",
    async_client=client,
)

# 定义请求设置以使用自动函数调用配置模型
request_settings = OpenAIChatPromptExecutionSettings(function_choice_behavior=FunctionChoiceBehavior.Auto())


async def main():
    # 根据给定的聊天记录和请求设置向模型发出请求
    # 内核包含模型将请求调用的示例
    response = await chat_service.get_chat_message_content(
        chat_history=chat_history, settings=request_settings, kernel=kernel
    )
    assert response is not None

    """
    Note: In the auto function calling process, the model determines it can invoke the 
    `BookTravelPlugin` using the `book_flight` function, supplying the necessary arguments. 

    For example:

    "tool_calls": [
        {
            "id": "call_abc123",
            "type": "function",
            "function": {
                "name": "BookTravelPlugin-book_flight",
                "arguments": "{'location': 'New York', 'date': '2025-01-01'}"
            }
        }
    ]

    Since the location and date arguments are required (as defined by the kernel function), if the 
    model lacks either, it will prompt the user to provide them. For instance:

    User: Book me a flight to New York.
    Model: Sure, I'd love to help you book a flight. Could you please specify the date?
    User: I want to travel on January 1, 2025.
    Model: Your flight to New York on January 1, 2025, has been successfully booked. Safe travels!
    """

    print(f"`{response}`")
    # Example AI Model Response: `您的旅行已成功预定，将于2025年8月13日出发前往江苏南京。如需预订酒店或安排当地交通，可随时告知我哦！`

    # Add the model's response to our chat history context
    chat_history.add_assistant_message(response.content)


if __name__ == "__main__":
    asyncio.run(main())
